﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Net;
using System.IO;
using Lswweb.Common;

namespace Lswweb.Domain.Payment.Paypal
{
    public class PaypalIPN : IPaymentIPN
    {
        private HttpContext context;

        public PaypalIPN(HttpContext context)
            : this(context, false) { }

        public PaypalIPN(HttpContext context,bool enableSandBox)
        {
            this.context = context;
            this.EnableSandBox = enableSandBox;
            this.VerifyState = this.GetResponseVerifyState();

            if (this.VerifyState != PaymentVerifyState.Invalid)
                this.PaymentState = PaymentState.Paid;

            this.OrderId = context.Request.Form["item_name"];
            this.PaymentAccount = context.Request.Form["payer_email"];
            this.PaymentAmount =context.Request.Form["payment_gross"].As<decimal>();
            this.PaymentCurrency = context.Request.Form["mc_currency"];

        }

        /// <summary>
        /// 启用SandBox调试模式
        /// </summary>
        public bool EnableSandBox { get; set; }

        /// https://www.paypal.com/xclick/
        /// https://www.paypal.com/cgi-bin/webscr
        /// https://www.sandbox.paypal.com/cgi-bin/webscr
        private string PaypalInterfaceUrl
        {
            get
            {
                return this.EnableSandBox
                    ? "https://www.sandbox.paypal.com/cgi-bin/webscr"
                    : "https://www.paypal.com/cgi-bin/webscr";
            }
        }

        #region IPaymentIPN

        public string OrderId { get; private set; }

        public PaymentVerifyState VerifyState { get; private set; }

        public PaymentState PaymentState { get; private set; }

        public string PaymentMethod
        {
            get { return "Paypal"; }
        }

        public string PaymentAccount { get; private set; }

        public decimal PaymentAmount { get; private set; }

        public string PaymentCurrency { get; private set; }

        #endregion

        private PaymentVerifyState GetResponseVerifyState()
        {
            ///生成验证IPN的字符串
            string requestStr = "&cmd=_notify-validate";
            using (StreamReader reader = new StreamReader(this.context.Request.InputStream))
            {
                requestStr = reader.ReadToEnd() + requestStr;
            }

            ///生成验证IPN的WebRequest对像
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(PaypalInterfaceUrl);
            request.Method = "POST";
            //request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = requestStr.Length;

            ///将IPN验证字符串写入到Post的WebRequest对像中
            using (StreamWriter requestWriter = new StreamWriter(request.GetRequestStream()))
            {
                requestWriter.Write(requestStr);
            }

            ///发送post并读取返回结果
            using (StreamReader responseReader = new StreamReader(request.GetResponse().GetResponseStream()))
            {
                switch (responseReader.ReadToEnd())
                {
                    case "VERIFIED":
                        return PaymentVerifyState.Verified;
                    case "INVALID":
                        return PaymentVerifyState.Invalid;
                    default:
                        return PaymentVerifyState.Unknown;
                }
            }
        }
    }
}
